/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package edu.ncsu.csc573.project1.util;

import edu.ncsu.csc573.project1.util.Constants.Status;
import java.util.LinkedList;
import java.util.Scanner;
import java.util.StringTokenizer;
import java.util.regex.MatchResult;
import java.util.regex.Pattern;

/**
 *
 * @author svpendse1
 */
public class PSResponse {
    private String version;
    private Status status;
    private LinkedList<RfcField> responseList;

    private PSResponse() {
    }

    public static class PSResponseBuilder {
        String version;
        Status status;
        LinkedList<RfcField> responseList;

        public PSResponseBuilder version(String version) {
            this.version = version;
            return this;
        }
        
        public PSResponseBuilder status(Status status) {
            this.status = status;
            return this;
        }

        public PSResponseBuilder responseList(LinkedList<RfcField> responseList) {
            this.responseList = responseList;
            return this;
        }
        
        public PSResponse build() {
            return new PSResponse(this);
        }
    }

    public LinkedList<RfcField> getResponseList() {
        if (responseList == null) {
            responseList = new LinkedList<RfcField>();
        }
        return responseList;
    }

    public void setResponseList(LinkedList<RfcField> responseList) {
        this.responseList = responseList;
    }

    public Status getStatus() {
        return status;
    }

    public void setStatus(Status status) {
        this.status = status;
    }

    public String getVersion() {
        return version;
    }

    public void setVersion(String version) {
        this.version = version;
    }

    
    private PSResponse(PSResponseBuilder builder) {
        this.version = builder.version;
        this.status = builder.status;
        this.responseList = builder.responseList;
    }

    public String getResponseMessage() {
        StringBuilder output = new StringBuilder();

        //Line 1
        output.append(version);
        output.append(" ");
        output.append(status.getCode());
        output.append(" ");
        output.append(status.getPhrase());
        output.append("\r\n");

        //Line 2
        output.append("\r\n");
        
        //RFC lines
        if (responseList != null) {
            for (int i = 0; i < responseList.size(); ++i) {
                RfcField currentField = responseList.get(i);
                output.append("RFC ");
                output.append(currentField.getRfcNumber());
                output.append(" ");
                output.append(currentField.getRfcTitle().replaceAll(" ", "_"));
                output.append(" ");
                output.append(currentField.getHostName());
                output.append(" ");
                output.append(currentField.getUploadPortNumber());
                output.append("\r\n");
            }
            //Last line
            output.append("\r\n");
        }
        return output.toString(); 
    }

    //Parse a message of type PSResponse from an input string
    public static PSResponse parseFromString(String input) {
        PSResponse output = null;
        try {
            Scanner scanner = new Scanner(input);

            String version = scanner.next();

            if (! version.equals(Constants.kVersion)) {
                System.out.println("Incompatible version " + version);
            }
            int statuscode = scanner.nextInt();
            String phrase = scanner.nextLine().trim();
            Status status = Status.constructFromPhraseAndCode(phrase, statuscode);
            if (status == null) {
                System.out.println("Unknown status code : " + phrase + " " + statuscode);
            } else if (status == Status.NOT_FOUND) {
                output = new PSResponse.PSResponseBuilder().version(version).status(status).build();
                return output;
            }
            scanner.skip("\r\n");
            LinkedList<RfcField> responseList = new LinkedList<RfcField>();
            while (scanner.hasNext("RFC")) {
                scanner.skip(("RFC "));
                int rfcNumber = scanner.nextInt();
                String rfcTitle = scanner.next();   

                //!TODO : NEED A SPECIAL DELIMITER TO DISTINGUISH BETWEEN TITLE SPACES AND <SP>
                String hostname = scanner.next().replaceAll("_", " ").trim();
                int portNumber = scanner.nextInt();
                responseList.add(new RfcField(rfcNumber, rfcTitle, hostname, portNumber));
                scanner.skip("\r\n");
            }
            scanner.skip("\r\n");
            output = new PSResponse.PSResponseBuilder().version(version).status(status).responseList(responseList).build();
            return output;
        } catch (Exception e) {
            System.out.println("Bad Request");
            e.printStackTrace();
        } 
        return null;        
    }

    public static void main(String[] args) {
        PSResponse response = new PSResponse.PSResponseBuilder().version("P2P-CI/1.0").status(Status.OK).responseList(null).build();
        response.getResponseList().add(new RfcField(1000, "hello", "127.0.0.1", 8001));
        response.getResponseList().add(new RfcField(1001, "hello2", "127.0.0.1", 9001));
        
        System.out.println(response.getResponseMessage().length());
        PSResponse.parseFromString(response.getResponseMessage());
        System.out.println(PSResponse.parseFromString(response.getResponseMessage()).getResponseMessage().length());
    }
}
